package LeetDev.a3d;

import javax.microedition.khronos.opengles.GL10;

public class Material {
	private String m_matname;
	private float m_tmpDiffuse[]=new float[4];
	private float m_diffuse[]=new float[4];
	private float m_specular[]=new float[4];
	private float m_ambient[]=new float[4];
	private float m_emission[]=new float[4];
	private float m_shininess;
	private boolean m_containsAlpha;
	private Texture m_textures[];

	public Material(FileInput fin, GL10 gl) throws Exception
	{
		m_textures=new Texture[1];
		m_textures[0]=null;
		m_containsAlpha=false;
		m_matname=fin.popString();
		m_specular[3]=m_ambient[3]=m_emission[3]=1;
		m_diffuse[0]=fin.popFloat();m_diffuse[1]=fin.popFloat();m_diffuse[2]=fin.popFloat();
		m_specular[0]=fin.popFloat();m_specular[1]=fin.popFloat();m_specular[2]=fin.popFloat();
		m_ambient[0]=fin.popFloat();m_ambient[1]=fin.popFloat();m_ambient[2]=fin.popFloat();
		m_emission[0]=fin.popFloat();m_emission[1]=fin.popFloat();m_emission[2]=fin.popFloat();
		m_shininess=fin.popFloat();
		m_diffuse[3]=fin.popFloat();
		m_diffuse[3]=1-m_diffuse[3];
		if(m_diffuse[3]!=1) {m_containsAlpha=true;}
		int bitmapmask,mask;
		bitmapmask=fin.popInt();
		mask=1;
		boolean onlyonetexture=true;
		while(bitmapmask!=0)
		{
			if((bitmapmask&0x1)!=0)
			{
				Texture tmptexture=new Texture(fin,mask);
				boolean newtexture=true;
				for(int t=0;t<Texture.s_globalTextures.size();++t)
				{
					Texture tmp=(Texture)Texture.s_globalTextures.elementAt(t);
					if(tmp.isSame(tmptexture))
					{
						tmptexture=tmp;
						tmptexture.addRef();
						newtexture=false;
						break;
					}
				}
				if(onlyonetexture)	// As OpenGL ES 1.0 doesn't handle multitexturing, we simply skip storing more than one texture per material.
				{
					if(newtexture)
					{
						Texture.s_globalTextures.add(tmptexture);
					}
					m_textures[0]=tmptexture;
					onlyonetexture=false;
				}
			}
			bitmapmask>>=1;
			mask+=mask;
		}
		compile(gl,true);
	}

	public void destruct(GL10 gl)
	{
		for(int t=0;t<m_textures.length;++t)
		{
			if(m_textures[t]!=null)
			{
				m_textures[t].destruct(gl);
			}
		}
	}

	public void compile(GL10 gl, boolean includetextures) throws Exception
	{
		for(int t=0;t<m_textures.length;++t)
		{
			if(m_textures[t]!=null)
			{
				System.out.println("Loading map: "+m_textures[t].GetMapName());
				try
				{
					m_textures[t].compile(gl);
				}
				catch(Exception e)
				{
					System.out.println("Failed loading map: "+m_textures[t].GetMapName());
					throw e;
				}
				if(m_textures[t].haveAlpha()) {m_containsAlpha=true;}
			}
		}
	}
	
	public boolean isTextured()
	{
		return(m_textures[0]!=null);
	}

	public boolean haveAlpha()
	{
		return(m_containsAlpha);
	}
	
	public String getName()
	{
		return(m_matname);
	}
	
	public void use(GL10 gl)
	{
		gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_SPECULAR,m_specular,0);
		gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_AMBIENT,m_ambient,0);
		gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_EMISSION,m_emission,0);
		gl.glMaterialf(GL10.GL_FRONT_AND_BACK,GL10.GL_SHININESS,m_shininess);

		if(m_textures[0]!=null)
		{
			float strength=m_textures[0].GetStrength();
			m_tmpDiffuse[0]=m_diffuse[0]*strength;
			m_tmpDiffuse[1]=m_diffuse[1]*strength;
			m_tmpDiffuse[2]=m_diffuse[2]*strength;
			m_tmpDiffuse[3]=1-((1-m_diffuse[3])*strength);
			gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_DIFFUSE,m_tmpDiffuse,0);
			m_textures[0].use(gl,0);
		}
		else
		{
			gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_DIFFUSE,m_diffuse,0);
		}
		if(m_containsAlpha)
		{
			gl.glEnable(GL10.GL_BLEND);
			gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA);
		}
		else
		{
			gl.glDisable(GL10.GL_BLEND);
		}
	}
	
}
